/*******************************************************************************
 * Copyright (c) 2006 CEA List.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     CEA List - initial API and implementation
 *******************************************************************************/
package com.cea.papyrus.core.treeeditpart;

import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.UnexecutableCommand;
import org.eclipse.gef.ui.actions.SelectionAction;
import org.eclipse.jface.resource.ImageDescriptor;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.swt.graphics.Image;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.uml2.uml.Element;

import com.cea.papyrus.core.PapyrusPlugin;
import com.cea.papyrus.core.commands.UMLElementCreateCommand;

/**
 * Action that creates uml element.
 * 
 * @author Remi SCHNEKENBURGER
 * FIXME should implements SelectionAction (gef) and be registered in the editor action registry
 */
public class CreateElementActionWithCommand extends SelectionAction {

	/**
	 * prefix for the ID of the action.
	 */
	public static final String PREFIX_ID = "CREATE_ELEMENT_ACTION_";
	
	/**
	 * type of element to create.
	 */
	protected Class elementClass;

	/**
	 * To create an elemnt from the viewer.
	 * 
	 * @param viewer 	 * @param elementClass to create
	 * @param part 
	 */
	public CreateElementActionWithCommand(IWorkbenchPart part, Class elementClass){
		super(part);
		
		this.elementClass = elementClass;

		final String simpleName = elementClass.getSimpleName();
		setId(getId(elementClass));
		setText(simpleName);
		setToolTipText("Create a new "+simpleName);
		
		Image image= PapyrusPlugin.UML_LABEL_PROVIDER.getImage(elementClass, null);
		setImageDescriptor(ImageDescriptor.createFromImage(image));
		
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.jface.action.Action#run()
	 */
	/**
	 * 
	 */
	@Override
	public void run() {
		if(getCommandStack()!= null) {
			getCommandStack().execute(getCommand());
		}
	}
	
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.ui.actions.SelectionAction#dispose()
	 */
	@Override
	public void dispose() {
		this.elementClass = null;
		this.setWorkbenchPart(null);
		this.setSelectionProvider(null);
		super.dispose();
	}
	
	/*
	 * (non-Javadoc) Method declared on IAction.
	 */
	/**
	 * 
	 * 
	 * @return 
	 */
	public boolean isEnabled() {
		return calculateEnabled();
	}

	/**
	 * Calculates if the action is runnable or not.
	 * 
	 * @return <code>true</code> if the action can be executed
	 */
	protected boolean calculateEnabled() {
		Command command = getCommand();
		if( command != null) {
			return command.canExecute();
		} else {
			return false;
		}
	}
	
	/**
	 * returns the CreateElementCommand for the first element of the current selection.
	 * 
	 * @return the CreateElementCommand that can be executed or an {@link UnexecutableCommand}
	 */
	private Command getCommand() {
		// get Selection
		// ISelection selection = editor.getSelection();
		Object e= ((IStructuredSelection)getSelection()).getFirstElement();
		// get Command for selection. Selection should be a IUMLObjectEditPart
		if(e instanceof ElementTreeEditPart) {
			Element parent =  ((ElementTreeEditPart)e).getUmlElement();
			// element should not be an element import => no create command on element import
			if(!((ElementTreeEditPart)e).isElementImport()) {
				return new UMLElementCreateCommand(elementClass, parent);
			}
		}
		return UnexecutableCommand.INSTANCE;
	}
	
	/* (non-Javadoc)
	 * @see org.eclipse.gef.ui.actions.SelectionAction#setSelection(org.eclipse.jface.viewers.ISelection)
	 */
	/**
	 * 
	 * 
	 * @param selection 
	 */
	public void setSelection(ISelection selection) {
		// make this method visible
		super.setSelection(selection);
	}
	
	/* (non-Javadoc)
	 * @see java.lang.Object#toString()
	 */
	/**
	 * 
	 * 
	 * @return 
	 */
	public String toString() {
		return "CreateElementAction [id:"+getId()+", metaclass: "+elementClass.getSimpleName()+", selection: "+getSelection()+")";
	}
	
	/**
	 * returns the id for this action, given the element class.
	 * 
	 * @param elementClass the Class linked to this create action
	 * 
	 * @return the string representing the id of the action
	 */
	public static String getId(Class elementClass) {
		return PREFIX_ID+elementClass.getSimpleName();
	}
}
